﻿using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using ToracTechnologies.ExpressionTreeLibrary.DynamicApi;
using ToracTechnologies.ExpressionTreeLibrary.DynamicApi.Framework;
using ToracTechnologies.ExpressionTreeLibrary.ExtensionMethods.IEnumerable;

namespace ToracTechnologies.ExpressionTree.Testing.DynamicApi
{

    [TestClass]
    public class LinqDynamicUnitTest
    {

        #region Select

        [TestMethod]
        public void Select_Test1()
        {
            var lst = Jason.CreateDummyList(100);

            //grab the field from the parameter builder
            var paramBuilderResults = ParameterBuilder.BuildParameterFromStringName<Jason>("Id");

            var ids = lst.Select(ExpressionBuilder.Select<Jason, int>(paramBuilderResults).Compile()).ToArray();

            for (int i = 0; i < ids.Length; i++)
            {
                Assert.AreEqual(i, ids[i]);
            }
        }

        [TestMethod]
        public void Select_Test2()
        {
            var lst = Jason.CreateDummyList(100);

            //grab the field from the parameter builder
            var paramBuilderResults = ParameterBuilder.BuildParameterFromLinqPropertySelector<Jason>(x => x.Id);

            var ids = lst.Select(ExpressionBuilder.Select<Jason, int>(paramBuilderResults).Compile()).ToArray();

            for (int i = 0; i < ids.Length; i++)
            {
                Assert.AreEqual(i, ids[i]);
            }
        }

        #endregion

        #region String Contains

        [TestMethod]
        public void StringContains_Test1()
        {
            var lst = Jason.CreateDummyList(100).ToList();

            //make sure it handles a null value
            lst.Add(new Jason
            {
                txt = null
            });

            var selector = LinqUtilities.StringContains<Jason>("txt", "Test_55", false);

            var result = lst.AsQueryable().Where(selector).ToArray();

            Assert.AreEqual(1, result.Count());
            Assert.AreEqual(55, result.ElementAt(0).Id);
            Assert.AreEqual("Test_55", result.ElementAt(0).txt);
        }

        [TestMethod]
        public void StringContains_Test2()
        {
            var lst = Jason.CreateDummyList(100).ToList();

            //make sure it handles a null value
            lst.Add(new Jason
            {
                 txt = null
            });

            var selector = LinqUtilities.StringContains<Jason>("txt", "Test_55", true);

            var result = lst.AsQueryable().Where(selector).ToArray();

            Assert.AreEqual(1, result.Count());
            Assert.AreEqual(55, result.ElementAt(0).Id);
            Assert.AreEqual("Test_55", result.ElementAt(0).txt);
        }

        [TestMethod]
        public void StringContains_Test3()
        {
            var lst = Jason.CreateDummyList(100);

            var selector = LinqUtilities.StringContains<Jason>("txt", "TEST_55", false);

            var result = lst.AsQueryable().Where(selector).ToArray();

            Assert.AreEqual(1, result.Count());
            Assert.AreEqual(55, result.ElementAt(0).Id);
            Assert.AreEqual("Test_55", result.ElementAt(0).txt);
        }

        #endregion

        #region Order By

        [TestMethod]
        public void OrderByLinqStatement_ByAscending_FuncReturnWay_Test1()
        {
            var lst = Jason.CreateDummyList(100);

            var selector = LinqUtilities.OrderByLinqStatement<Jason>("Id");

            var result = lst.AsQueryable().OrderBy(selector).ToArray();

            Assert.AreEqual(100, result.Count());
            Assert.AreEqual(0, result[0].Id);
            Assert.AreEqual(99, result[result.Count() - 1].Id);
        }

        [TestMethod]
        public void OrderByLinqStatement_ByDesending_FuncReturnWay_Test1()
        {
            var lst = Jason.CreateDummyList(100);

            var selector = LinqUtilities.OrderByLinqStatement<Jason>("Id");

            var result = lst.AsQueryable().OrderByDescending(selector).ToArray();

            Assert.AreEqual(100, result.Count());
            Assert.AreEqual(99, result[0].Id);
            Assert.AreEqual(0, result[result.Count() - 1].Id);
        }

        [TestMethod]
        public void OrderByLinqStatement_ByAscending_IQueryableWay_Test1()
        {
            var result = LinqUtilities.OrderByLinqStatement(Jason.CreateDummyList(100).AsQueryable(), "Id", true).ToArray();

            Assert.AreEqual(100, result.Count());
            Assert.AreEqual(0, result[0].Id);
            Assert.AreEqual(99, result[result.Count() - 1].Id);
        }

        [TestMethod]
        public void OrderByLinqStatement_ByDesending_IQueryableWay_Test1()
        {
            var result = LinqUtilities.OrderByLinqStatement(Jason.CreateDummyList(100).AsQueryable(), "Id", false).ToArray();

            Assert.AreEqual(100, result.Count());
            Assert.AreEqual(99, result[0].Id);
            Assert.AreEqual(0, result[result.Count() - 1].Id);
        }

        #endregion

        #region Paginate

        [TestMethod]
        public void Paginate_ByCollection_Test1()
        {
            var lst = Jason.CreateDummyList(100);

            var selector = LinqUtilities.PaginateResults(lst, 2, 10).ToArray();

            Assert.AreEqual(10, selector.Count());
            Assert.AreEqual(10, selector.ElementAt(0).Id);
            Assert.AreEqual(11, selector.ElementAt(1).Id);
            Assert.AreEqual(12, selector.ElementAt(2).Id);
        }

        [TestMethod]
        public void PaginateByIEnumerableExtensionMethod_ByCollection_Test1()
        {
            var lst = Jason.CreateDummyList(100);

            var selector = lst.PaginateResults(2, 10).ToArray();

            Assert.AreEqual(10, selector.Count());
            Assert.AreEqual(10, selector.ElementAt(0).Id);
            Assert.AreEqual(11, selector.ElementAt(1).Id);
            Assert.AreEqual(12, selector.ElementAt(2).Id);
        }

        [TestMethod]
        public void Paginate_ByIQueryable_Test1()
        {
            var lst = Jason.CreateDummyList(100);

            var selector = LinqUtilities.PaginateResults(lst.AsQueryable(), 2, 10).ToArray();

            Assert.AreEqual(10, selector.Count());
            Assert.AreEqual(10, selector.ElementAt(0).Id);
            Assert.AreEqual(11, selector.ElementAt(1).Id);
            Assert.AreEqual(12, selector.ElementAt(2).Id);
        }

        #endregion

    }
}


